#ifndef CAMERAETH0_H
#define CAMERAETH0_H

#include "camera.h"
#include "mvhikcamera.h"
#include "source/parametermodel.h"
#include <opencv2/opencv.hpp>

class CameraEth0 : public Camera {
    Q_OBJECT
    Q_PROPERTY(bool isOpened READ getIsOpened NOTIFY isOpenedChanged);
    Q_PROPERTY(QVariantMap cameraInfoDetal READ cameraInfoDetal NOTIFY cameraInfoDetalChanged)

    Q_PROPERTY(float exposureTime READ exposureTime WRITE setExposureTime NOTIFY exposureTimeChanged)
    Q_PROPERTY(int exposureAuto READ exposureAuto WRITE setExposureMode NOTIFY exposureAutoChanged)
    Q_PROPERTY(float gain READ gain WRITE setGain NOTIFY gainChanged)
    Q_PROPERTY(int gainAuto READ gainAuto WRITE setGainAuto NOTIFY gainAutoChanged)
    Q_PROPERTY(float balanceRatio READ balanceRatio WRITE setBalanceRatio NOTIFY balanceRatioChanged)
    Q_PROPERTY(int balanceAuto READ balanceAuto WRITE setBalanceAuto NOTIFY balanceAutoChanged)
    Q_PROPERTY(bool cameraHorizontal READ cameraHorizontal WRITE setcameraHorizontal NOTIFY cameraHorizontalChanged)
    Q_PROPERTY(bool cameraVertical READ cameraVertical WRITE setcameraVertical NOTIFY cameraVerticalChanged)

    Q_PROPERTY(int deviceMaxThroughput READ deviceMaxThroughput NOTIFY deviceMaxThroughputChanged)
    Q_PROPERTY(QString imageCompressionMode READ imageCompressionMode NOTIFY imageCompressionModeChanged)
    //Q_PROPERTY(int pixelFormat WRITE setPixelFormat)
    Q_PROPERTY(QVariantList cameraImgRoi READ cameraImgRoi NOTIFY cameraImgRoiChanged)
    // Q_PROPERTY(QVariantList cameraSourceImgSize READ cameraSourceImgSize NOTIFY cameraSourceImgSizeChanged)


public:
    Q_INVOKABLE void setROI(int x, int y, int width, int height);
    Q_INVOKABLE void restartCamera();
    Q_INVOKABLE void resetRoi();
    Q_INVOKABLE void capRelease() override;
    Q_INVOKABLE void capOpen() override;
    //czh
    Q_INVOKABLE void photograph();

    enum CameraStatus {
        Error,
        Closed,
        Opened,
        Paused,
        Running,
    };

    static CameraEth0& getInstance();

    float exposureTime() const { return m_exposureTime; }
    int exposureAuto() const { return m_exposureAuto; }
    float gain() const { return m_gain; }
    int gainAuto() const { return m_gainAuto; }
    float balanceRatio() const { return m_balanceRatio; }
    int balanceAuto() const { return m_balanceAuto; }
    QVariantList cameraImgRoi() const { return m_cameraImgRoi; }
    bool cameraHorizontal() const { return cameraHorizontal_; }
    bool cameraVertical() const { return cameraVertical_; }

    void setExposureTime(float exposure);
    void setExposureMode(int mode);
    void setGain(float gain);
    void setGainAuto(int mode);
    void setBalanceRatio(float ratio);
    void setBalanceAuto(int mode);
    void setcameraHorizontal(bool mode);
    void setcameraVertical(bool mode);


    //void setPixelFormat(int format);

    QString imageCompressionMode() const {return m_imageCompressionMode;};
    int deviceMaxThroughput() const {return m_deviceMaxThroughput;};
    QString cameraInfo() const {return m_cameraInfo;};
    QVariantMap cameraInfoDetal() const {return m_cameraInfoDetal;};

    void readGain();
    void readBalanceRatio();
    void readImageCompressionMode();
    void readExposureTime();
    void readDeviceMaxThroughput();

    float getFrameRate();
    int getThroughput();

    cv::Mat getImage() override;
    bool getIsOpened() override;

    void monitorParameters();
signals:
    void exposureTimeChanged();
    void exposureAutoChanged();
    void gainChanged();
    void gainAutoChanged();
    void balanceRatioChanged();
    void balanceAutoChanged();
    void cameraImgRoiChanged();
    void isOpenedChanged();
    void cameraInfoDetalChanged();
    void deviceMaxThroughputChanged();
    void imageCompressionModeChanged();
    void cameraHorizontalChanged();
    void cameraVerticalChanged();
    void cameraResetOver();
    void cameraSetOver();

public slots:
    void updateCameraInfo();
    void configDataChanged(QString Category,QString key);
    void valueTableLoad();

private:
    CameraEth0(QObject *parent = nullptr);
    ~CameraEth0();

    float m_exposureTime;
    int m_exposureAuto;
    float m_gain;
    int m_gainAuto;
    float m_balanceRatio;
    int m_balanceAuto;
    QVariantList m_cameraImgRoi;
    bool cameraVertical_;
    bool cameraHorizontal_;


    QString m_imageCompressionMode;

    int m_deviceMaxThroughput;
    QString m_cameraInfo;
    CameraStatus currentStatus;
    QVariantMap m_cameraInfoDetal;
    CMvCamera* m_pcMyCamera;
    bool isOpened;
    mutable std::mutex mtx; // 互斥锁

    void getCameraInfo(MV_CC_DEVICE_INFO *pDeviceInfo);
    void checkAndAdjustRoi();
    void openCameraUpdateParam();
    QVariantList getAndsetAdjustedCameraRoi();

};

#endif // CAMERAETH0_H
